home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / libs / winlib-0.0 / winlib-0 / win / menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-02  |  7.9 KB  |  376 lines

  1. /*
  2.  * WinLIB
  3.  * Menu handling and manipulation routines
  4.  */
  5.  
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "winlib.h"
  9. #include "internal.h"
  10. #include "config.h"
  11.  
  12. int _has_menu, _changed, _cur_item;
  13.  
  14. void _top_menu_link(void)
  15. {
  16.     while(_menutree->prev)
  17.     _menutree = _menutree->prev;
  18. }
  19.  
  20. void _create_menubar(void)
  21. {
  22.     int i;
  23.  
  24.     /* We have a menu now! */
  25.     _has_menu = TRUE;
  26.  
  27.     /* Create the new window and make it a panel */
  28.     _menu_win = newwin(1, stdscr->_maxx + 1, 0, 0);
  29.     _menu_pan = new_panel(_menu_win);
  30.  
  31.     /* Draw the inverse border to signify the menu */
  32.     wattron(_menu_win, A_REVERSE);
  33.     for(i = 0; i < stdscr->_maxx + 1; i++)
  34.     mvwaddch(_menu_win, 0, i, ' ');
  35.     wattroff(_menu_win, A_REVERSE);
  36. }
  37.  
  38. int _menustruct_length(void)
  39. {
  40.     return(sizeof(struct _menustruct));
  41. }
  42.  
  43. void _add_menu_link(void)
  44. {
  45.     /* Allocate memory for the new menu structure */
  46.     _menutree->next = (MENU *) malloc(_menustruct_length());
  47.  
  48.     /* And make the next's previous member equal to the current one
  49.        that we just created */
  50.     _menutree->next->prev = _menutree;
  51.     _menutree = _menutree->next;
  52.  
  53.     /* And let it know that this is the end of the chain */
  54.     _menutree->next = NULL;
  55. }
  56.  
  57. void _unselect_menu(void)
  58. {
  59.     _top_menu_link();
  60.  
  61.     while(_menutree->next) {
  62.     wattron(_menu_win, A_REVERSE);
  63.     mvwaddstr(_menu_win, 0, _menutree->x, _menutree->title);
  64.     _menutree = _menutree->next;
  65.     _menutree->selected = FALSE;
  66.     }
  67.  
  68.     _cur_title = 0;
  69.     _cur_item = -1;
  70.  
  71.     if (_showing_menu) {
  72.     del_panel(_menu_area_pan);
  73.     delwin(_menu_area);
  74.     _showing_menu = FALSE;
  75.     }
  76. }
  77.  
  78. void _unselect_menubar(void)
  79. {
  80.     _top_menu_link();
  81.  
  82.     while(_menutree->next) {
  83.     if ((_menutree->selected) &&
  84.         (_cur_title != _menutree->index)) {
  85.         wattron(_menu_win, A_REVERSE);
  86.         mvwaddstr(_menu_win, 0, _menutree->x, _menutree->title);
  87.  
  88.         _menutree->selected = FALSE;
  89.     }
  90.  
  91.     _menutree = _menutree->next;
  92.     }
  93.  
  94.     _cur_item = -1;
  95. }
  96.  
  97. void _create_dropdown(void)
  98. {
  99.     if (!_showing_menu) {
  100.     int i;
  101.  
  102.     _menu_area = newwin(_menutree->items + 1,
  103.                 strlen(_menutree->item[0].item) + 2,
  104.                 1, _menutree->x - 1);
  105.     _menu_area_pan = new_panel(_menu_area);
  106.  
  107.     for(i = 0; i < _menu_area->_maxy; i++) {
  108.         mvwaddch(_menu_area, i, 0, ACS_VLINE);
  109.         mvwaddch(_menu_area, i, _menu_area->_maxx, ACS_VLINE);
  110.     }
  111.  
  112.     for(i = 0; i < _menu_area->_maxx; i++)
  113.         mvwaddch(_menu_area, _menu_area->_maxy, i, ACS_HLINE);
  114.  
  115.     mvwaddch(_menu_area, _menu_area->_maxy, 0, ACS_LLCORNER);
  116.     mvwaddch(_menu_area, _menu_area->_maxy, _menu_area->_maxx, ACS_LRCORNER);
  117.  
  118.     for(i = 0; i < _menutree->items; i++)
  119.         mvwaddstr(_menu_area, i, 1, _menutree->item[i].item);
  120.  
  121.     _showing_menu = TRUE;
  122.  
  123.     Win_PlaySound(SOUND_MENUDROP);
  124.     }
  125. }
  126.  
  127. void _handle_menu(Gpm_Event *event)
  128. {
  129.     int found_inside = FALSE;
  130.  
  131.     _top_menu_link();
  132.  
  133.     while(_menutree->next) {
  134.     int sx, ex;
  135.  
  136.     sx = _menutree->x;
  137.     ex = _menutree->x + _menutree->title_len;
  138.  
  139.     if ((event->x >= sx) && (event->x <= ex)) {
  140.         if ((_cur_title != _menutree->index) &&
  141.         (_menutree->selected == FALSE)) {
  142.         wattroff(_menu_win, A_REVERSE);
  143.         mvwaddstr(_menu_win, 0, _menutree->x, _menutree->title);
  144.         wattron(_menu_win, A_REVERSE);
  145.  
  146.         _cur_title = _menutree->index;
  147.         _menutree->selected = TRUE;
  148.  
  149.         if (_showing_menu) {
  150.             del_panel(_menu_area_pan);
  151.             delwin(_menu_area);
  152.             _showing_menu = FALSE;
  153.         }
  154.  
  155.         _create_dropdown();
  156.         }
  157.  
  158.         found_inside = TRUE;
  159.     }
  160.  
  161.     _menutree = _menutree->next;
  162.     }
  163.  
  164.     if (!found_inside)
  165.     _unselect_menu();
  166.     else
  167.     _unselect_menubar();
  168. }
  169.  
  170. void _unselect_item(void)
  171. {
  172.     _top_menu_link();
  173.  
  174.     while(_menutree->next) {
  175.     if (_cur_title == _menutree->index) {
  176.         if (_cur_item != -1) {
  177.         wattroff(_menu_area, A_REVERSE);
  178.         mvwaddstr(_menu_area, _cur_item, 1, _menutree->item[_cur_item].item);
  179.  
  180.         _menutree->item[_cur_item].selected = FALSE;
  181.         }
  182.  
  183.         _cur_item = -1;
  184.  
  185.         return;
  186.     }
  187.  
  188.     _menutree = _menutree->next;
  189.     }
  190. }
  191.  
  192. void _handle_menu_selection(Gpm_Event *event)
  193. {
  194.     _top_menu_link();
  195.  
  196.     while(_menutree->next) {
  197.     if (_cur_title == _menutree->index) {
  198.         int sx, ex;
  199.  
  200.         sx = _menu_area->_begx + 1;
  201.         ex = sx + strlen(_menutree->item[0].item);
  202.  
  203.         if (event->type & (GPM_DOWN | GPM_DRAG)) {
  204.         if ((event->y >= 1) && (event->y <= _menutree->items + 1)) {
  205.             if ((_cur_item != -1) && (_cur_item != event->y - 1)) {
  206.             wattroff(_menu_area, A_REVERSE);
  207.             mvwaddstr(_menu_area, _cur_item, 1, _menutree->item[_cur_item].item);
  208.  
  209.             _menutree->item[_cur_item].selected = FALSE;
  210.             }
  211.  
  212.             _cur_item = event->y - 1;
  213.  
  214.             if (_menutree->item[_cur_item].type == MENU_SELECTABLE) {
  215.             wattron(_menu_area, A_REVERSE);
  216.             mvwaddstr(_menu_area, _cur_item, 1, _menutree->item[_cur_item].item);
  217.             wattroff(_menu_area, A_REVERSE);
  218.             _menutree->item[_cur_item].selected = TRUE;
  219.             }
  220.  
  221.             return;
  222.         }
  223.         } else {
  224.         if (_cur_item != -1) {
  225.             wattroff(_menu_area, A_REVERSE);
  226.             mvwaddstr(_menu_area, _cur_item, 1, _menutree->item[_cur_item].item);
  227.  
  228.             _menutree->item[_cur_item].selected = FALSE;
  229.         }
  230.  
  231.         if (_menutree->item[_cur_item].function) {
  232.             Win_PlaySound(SOUND_MENUSEL);
  233.             (_menutree->item[_cur_item].function)();
  234.         }
  235.  
  236.         _unselect_menu();
  237.  
  238.         _cur_item = -1;
  239.         _cur_title = 0;
  240.  
  241.         return;
  242.         }
  243.     }
  244.  
  245.     _menutree = _menutree->next;
  246.     }
  247. }
  248.  
  249. int Menu_AddTitle(char *title)
  250. {
  251.     if (!_has_menu) {
  252.     /* Create a menubar */
  253.     _create_menubar();
  254.  
  255.     /* Allocate our menutree stuff */
  256.     _menutree->title = (char *) malloc(strlen(title));
  257.     _menutree->x = 1;
  258.     _menutree->title_len = strlen(title);
  259.     _menutree->index = 0;
  260.     _menutree->items = 0;
  261.     _menutree->selected = FALSE;
  262.  
  263.     /* Copy the menu title to the menu tree and the menu pointer */
  264.     strcpy(_menutree->title, title);
  265.  
  266.     /* Add the first option in that menu */
  267.     wattron(_menu_win, A_REVERSE);
  268.     mvwaddstr(_menu_win, 0, _menutree->x, _menutree->title);
  269.     wattroff(_menu_win, A_REVERSE);
  270.  
  271.     /* Make this the first physical menu index */
  272.     _menutree->index = 1;
  273.  
  274.     /* Add the menu item to our internal menu pointer */
  275.     _add_menu_link();
  276.  
  277.     /* Change the library to know we have a menu */
  278.     _has_menu = TRUE;
  279.  
  280.     /* And return the index */
  281.     return(1);
  282.     }
  283.  
  284.     if (_menutree->prev) {
  285.     int idx;
  286.  
  287.     /* Allocate memory, copy and set defaults */
  288.     _menutree->title = (char *) malloc(strlen(title));
  289.     _menutree->title_len = strlen(title);
  290.     _menutree->index = 0;
  291.     _menutree->items = 0;
  292.     _menutree->selected = FALSE;
  293.     strcpy(_menutree->title, title);
  294.  
  295.     /* Calculate this new menu item's X position */
  296.     _menutree->x = _menutree->prev->x + _menutree->prev->title_len;
  297.  
  298.     /* And draw this new item on the menubar */
  299.     wattron(_menu_win, A_REVERSE);
  300.     mvwaddstr(_menu_win, 0, _menutree->x, _menutree->title);
  301.     wattroff(_menu_win, A_REVERSE);
  302.  
  303.     /* Increase the previous index and make it this one */
  304.     idx = _menutree->prev->index + 1;
  305.     _menutree->index = idx;
  306.  
  307.     /* And add it to the link again */
  308.     _add_menu_link();
  309.  
  310.     /* And return the index */
  311.     return(idx);
  312.     }
  313.  
  314.     /* Whoops!  Some other error! */
  315.     return(0);
  316. }
  317.  
  318. int Menu_AddItem(int index, char *item, int type, void *function)
  319. {
  320.     _top_menu_link();
  321.  
  322.     while(_menutree->next) {
  323.     if (_menutree->index == index) {
  324.         int x;
  325.  
  326.         x = _menutree->items;
  327.         _menutree->item[x].item = malloc(strlen(item));
  328.  
  329.         strcpy(_menutree->item[x].item, item);
  330.         _menutree->item[x].type = type;
  331.         _menutree->item[x].selected = FALSE;
  332.  
  333.         _menutree->item[x].function = (function != NULL) ? function : NULL;
  334.  
  335.         _menutree->items++;
  336.  
  337.         return(x);
  338.     }
  339.  
  340.     _menutree = _menutree->next;
  341.     }
  342.  
  343.     return(-1);
  344. }
  345.  
  346. int Menu_AddCheck(int index, char *str, int checked)
  347. {
  348.     _top_menu_link();
  349.  
  350.     while(_menutree->next) {
  351.     if (_menutree->index == index) {
  352.         int x;
  353.  
  354.         for (x = 0; x < _menutree->items; x++) {
  355.         if (strstr(_menutree->item[x].item, str)) {
  356.             if ((_menutree->item[x].item[1] == '*') && (checked == FALSE)) {
  357.             _menutree->item[x].item[1] = ' ';
  358.             return TRUE;
  359.             }
  360.  
  361.             if ((_menutree->item[x].item[1] == ' ') && (checked)) {
  362.             _menutree->item[x].item[1] = '*';
  363.             return TRUE;
  364.             }
  365.         }
  366.         }
  367.  
  368.         return FALSE;
  369.     }
  370.  
  371.     _menutree = _menutree->next;
  372.     }
  373.  
  374.     return FALSE;
  375. }
  376.